package main

import (
	"fmt"
	"math"

	//	"fmt"
	"strconv"
)

//	"strconv"
//"errors"
// "fmt"
// "math"

type DataType int

const (
	TypeNum         DataType = 0
	TypeInt         DataType = 1
	TypeString      DataType = 2
	TypeTuple       DataType = 3
	TypeList        DataType = 4
	TypeMap         DataType = 5
	TypeBuiltInFunc DataType = 6 //内建函数
	TypeClass       DataType = 7
	TypeObject      DataType = 8
	TypeVariable    DataType = 9
	TypeCall        DataType = 10
	TypeUserFunc    DataType = 11 //用户自定义方法
	TypePair        DataType = 12
	TypeModule      DataType = 13
	TypeBool        DataType = 14
	TypeNone        DataType = 15
	TypeNumArray    DataType = 16
	TypeStringArray DataType = 17
	TypeTextFile    DataType = 18
	TypeRange       DataType = 19
)

type ClauseTypeIndex int

const (
	ClauseType_STRING   ClauseTypeIndex = 15 //指字符串常量
	ClauseType_CONSTANT ClauseTypeIndex = 16 //指数字常量
	ClauseType_VAR      ClauseTypeIndex = 17 //指单值变量
	ClauseType_SINGLE   ClauseTypeIndex = 18 //指最普通的单条语句
	ClauseType_FOR      ClauseTypeIndex = 19 //FOR语句
	ClauseType_IF       ClauseTypeIndex = 21 //if语句
	ClauseType_WHILE    ClauseTypeIndex = 22 //while语句
)

type ListMethodIndex int

const (
	List_Append  ListMethodIndex = 20
	List_Pop     ListMethodIndex = 21
	List_Copy    ListMethodIndex = 22
	List_ToTuple ListMethodIndex = 23
)

//*************************************************

type DrAbstractObject struct {
	//Name  string //变量名称，或者是函数名称
	IObject
	Type  DataType
	class *DrClass //对象所属的类
	//用于存放浮点数、整数或者其它变量的指针
	members map[string]IObject
}
type DrBoolean struct {
	DrAbstractObject
	v bool
}

func NewBoolen(v bool) *DrBoolean {
	ob := new(DrBoolean)
	ob.Type = TypeBool
	ob.v = v
	return ob
}
func (self *DrBoolean) AsString() string {
	if self.v {
		return "True"
	} else {
		return "False"
	}
}
func (self *DrBoolean) Print(interp *Interpreter) {
	fmt.Println(self.AsString())
}

type DrNumber struct {
	DrAbstractObject
	Value float64
}

func (self *DrNumber) AsString() string {
	if (self.Value != 0 && math.Abs(self.Value) < 1e-4) || math.Abs(self.Value) > 1e5 {
		return strconv.FormatFloat(self.Value, 'e', 3, 64)
	} else {
		return strconv.FormatFloat(self.Value, 'f', 6, 64)
	}
}
func (self *DrNumber) Print(interp *Interpreter) {
	fmt.Print(self.AsString())
}
func (self *DrNumber) getDouble() float64 {
	return self.Value
}
func (self *DrNumber) getInt() int {
	return int(self.Value)
}

type DrInt struct {
	DrAbstractObject
	Value int
}

func NewInt(v int) *DrInt {
	result := new(DrInt)
	result.Type = TypeInt
	result.Value = v
	return result
}
func (self *DrInt) AsFloat() float64 {
	return float64(self.Value)
}
func (self *DrInt) AsString() string {
	return strconv.FormatInt(int64(self.Value), 10)
}
func (self *DrInt) Print(interp *Interpreter) {
	fmt.Print(self.AsString())
}

func (self *DrInt) getDouble() float64 {
	return float64(self.Value)
}
func (self *DrInt) getInt() int {
	return self.Value
}

func (self *DrNumber) Add(num IObject) IObject {
	return NewNum(self.Value + num.(*DrNumber).Value)
}

type DrClass struct {
	DrAbstractObject
	className     string
	parent        *DrClass
	classMethods  []*DrFunction       //类方法，不属于对象
	objectMethods []*DrAbstractObject //对象方法，其第一个参数是对象引用
}

func (self *DrAbstractObject) AsString() string {
	return "None"
}
func (self *DrAbstractObject) Print(interp *Interpreter) {
	panic("not implemented")
}

func (self *DrAbstractObject) getType() DataType {
	return self.Type
}

func NewInteger(value int) *DrInt {
	num := new(DrInt)
	num.Type = TypeInt
	num.Value = value
	return num
}
func NewNum(value float64) *DrNumber {
	num := new(DrNumber)
	num.Type = TypeNum
	num.Value = value
	return num
}
func (self *DrAbstractObject) getMembers() map[string]IObject {
	if self.Type != TypeObject {
		return self.members
	}
	return self.class.members
}
func (self *DrAbstractObject) executeMethod(funcName string, prams []IObject) IObject {

	return prams[0].executeMethod(funcName, prams)

	panic("not implemented for the method:" + funcName)

}

//********************************************************
